home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / cfb / cfbpixmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-15  |  10.5 KB  |  422 lines

  1. /***********************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24. /* pixmap management
  25.    written by drewry, september 1986
  26.  
  27.    on a monchrome device, a pixmap is a bitmap.
  28. */
  29.  
  30. #include "Xmd.h"
  31. #include "servermd.h"
  32. #include "pixmapstr.h"
  33. #include "cfbmskbits.h"
  34.  
  35. #include "cfb.h"
  36. #include "mi.h"
  37.  
  38. extern void mfbXRotatePixmap(), mfbYRotatePixmap();
  39.  
  40. #if (BITMAP_BIT_ORDER == MSBFirst)
  41. static int masktab[32] = 
  42.     {
  43.         0x00000000,
  44.         0x80000000,
  45.         0xC0000000,
  46.         0xE0000000,
  47.         0xF0000000,
  48.         0xF8000000,
  49.         0xFC000000,
  50.         0xFE000000,
  51.         0xFF000000,
  52.         0xFF800000,
  53.         0xFFC00000,
  54.         0xFFE00000,
  55.         0xFFF00000,
  56.         0xFFF80000,
  57.         0xFFFC0000,
  58.         0xFFFE0000,
  59.         0xFFFF0000,
  60.         0xFFFF8000,
  61.         0xFFFFC000,
  62.         0xFFFFE000,
  63.         0xFFFFF000,
  64.         0xFFFFF800,
  65.         0xFFFFFC00,
  66.         0xFFFFFE00,
  67.         0xFFFFFF00,
  68.         0xFFFFFF80,
  69.         0xFFFFFFC0,
  70.         0xFFFFFFE0,
  71.         0xFFFFFFF0,
  72.         0xFFFFFFF8,
  73.         0xFFFFFFFC,
  74.         0xFFFFFFFE
  75.     };
  76. #else
  77. static int masktab[32] =
  78.         {
  79.         0x00000000,
  80.         0x00000001,
  81.         0x00000003,
  82.         0x00000007,
  83.         0x0000000F,
  84.         0x0000001F,
  85.         0x0000003F,
  86.         0x0000007F,
  87.         0x000000FF,
  88.         0x000001FF,
  89.         0x000003FF,
  90.         0x000007FF,
  91.         0x00000FFF,
  92.         0x00001FFF,
  93.         0x00003FFF,
  94.         0x00007FFF,
  95.         0x0000FFFF,
  96.         0x0001FFFF,
  97.         0x0003FFFF,
  98.         0x0007FFFF,
  99.         0x000FFFFF,
  100.         0x001FFFFF,
  101.         0x003FFFFF,
  102.         0x007FFFFF,
  103.         0x00FFFFFF,
  104.         0x01FFFFFF,
  105.         0x03FFFFFF,
  106.         0x07FFFFFF,
  107.         0x0FFFFFFF,
  108.         0x1FFFFFFF,
  109.         0x3FFFFFFF,
  110.         0x7FFFFFFF
  111.         };
  112. #endif
  113.  
  114. PixmapPtr
  115. cfbCreatePixmap (pScreen, width, height, depth)
  116.     ScreenPtr    pScreen;
  117.     int        width;
  118.     int        height;
  119.     int        depth;
  120. {
  121.     register PixmapPtr pPixmap;
  122.     int size;
  123.  
  124.     if (depth != 1 && depth != PSZ)
  125.     return NullPixmap;
  126.  
  127.     size = PixmapBytePad(width, depth);
  128.     pPixmap = (PixmapPtr)xalloc(sizeof(PixmapRec) + (height * size));
  129.     if (!pPixmap)
  130.     return NullPixmap;
  131.     pPixmap->drawable.type = DRAWABLE_PIXMAP;
  132.     pPixmap->drawable.class = 0;
  133.     pPixmap->drawable.pScreen = pScreen;
  134.     pPixmap->drawable.depth = depth;
  135.     pPixmap->drawable.bitsPerPixel = depth;
  136.     pPixmap->drawable.id = 0;
  137.     pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  138.     pPixmap->drawable.x = 0;
  139.     pPixmap->drawable.y = 0;
  140.     pPixmap->drawable.width = width;
  141.     pPixmap->drawable.height = height;
  142.     pPixmap->devKind = size;
  143.     pPixmap->refcnt = 1;
  144.     pPixmap->devPrivate.ptr = (pointer)(pPixmap + 1);
  145.     return pPixmap;
  146. }
  147.  
  148. Bool
  149. cfbDestroyPixmap(pPixmap)
  150.     PixmapPtr pPixmap;
  151. {
  152.     if(--pPixmap->refcnt)
  153.     return TRUE;
  154.     xfree(pPixmap);
  155.     return TRUE;
  156. }
  157.  
  158. PixmapPtr
  159. cfbCopyPixmap(pSrc)
  160.     register PixmapPtr    pSrc;
  161. {
  162.     register PixmapPtr    pDst;
  163.     int        size;
  164.  
  165.     size = pSrc->drawable.height * pSrc->devKind;
  166.     pDst = (PixmapPtr) xalloc(sizeof(PixmapRec) + size);
  167.     if (!pDst)
  168.     return NullPixmap;
  169.     pDst->drawable = pSrc->drawable;
  170.     pDst->drawable.id = 0;
  171.     pDst->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  172.     pDst->devKind = pSrc->devKind;
  173.     pDst->refcnt = 1;
  174.     pDst->devPrivate.ptr = (pointer)(pDst + 1);
  175.     bcopy((char *)pSrc->devPrivate.ptr, (char *)pDst->devPrivate.ptr, size);
  176.     return pDst;
  177. }
  178.  
  179.  
  180. /* replicates a pattern to be a full 32 bits wide.
  181.    relies on the fact that each scnaline is longword padded.
  182.    doesn't do anything if pixmap is not a factor of 32 wide.
  183.    changes width field of pixmap if successful, so that the fast
  184.     cfbXRotatePixmap code gets used if we rotate the pixmap later.
  185.     cfbYRotatePixmap code gets used if we rotate the pixmap later.
  186.  
  187.    calculate number of times to repeat
  188.    for each scanline of pattern
  189.       zero out area to be filled with replicate
  190.       left shift and or in original as many times as needed
  191. */
  192. void
  193. cfbPadPixmap(pPixmap)
  194.     PixmapPtr pPixmap;
  195. {
  196.     register int width = (pPixmap->drawable.width) * (pPixmap->drawable.depth);
  197.     register int h;
  198.     register int mask;
  199.     register unsigned int *p;
  200.     register unsigned int bits; /* real pattern bits */
  201.     register int i;
  202.     int rep;                    /* repeat count for pattern */
  203.  
  204.     if (width >= 32)
  205.         return;
  206.  
  207.     rep = 32/width;
  208.     if (rep*width != 32)
  209.         return;
  210.  
  211.     mask = masktab[width];
  212.  
  213.     p = (unsigned int *)(pPixmap->devPrivate.ptr);
  214.     for (h=0; h < pPixmap->drawable.height; h++)
  215.     {
  216.         *p &= mask;
  217.         bits = *p;
  218.         for(i=1; i<rep; i++)
  219.         {
  220. #if (BITMAP_BIT_ORDER == MSBFirst) 
  221.             bits >>= width;
  222. #else
  223.         bits <<= width;
  224. #endif
  225.             *p |= bits;
  226.         }
  227.         p++;
  228.     }    
  229.     pPixmap->drawable.width = 32/(pPixmap->drawable.depth);
  230. }
  231.  
  232.  
  233. #ifdef notdef
  234. /*
  235.  * cfb debugging routine -- assumes pixmap is 1 byte deep 
  236.  */
  237. static cfbdumppixmap(pPix)
  238.     PixmapPtr    pPix;
  239. {
  240.     unsigned int *pw;
  241.     char *psrc, *pdst;
  242.     int    i, j;
  243.     char    line[66];
  244.  
  245.     ErrorF(  "pPixmap: 0x%x\n", pPix);
  246.     ErrorF(  "%d wide %d high\n", pPix->drawable.width, pPix->drawable.height);
  247.     if (pPix->drawable.width > 64)
  248.     {
  249.     ErrorF(  "too wide to see\n");
  250.     return;
  251.     }
  252.  
  253.     pw = (unsigned int *) pPix->devPrivate.ptr;
  254.     psrc = (char *) pw;
  255.  
  256. /*
  257.     for ( i=0; i<pPix->drawable.height; ++i )
  258.     ErrorF( "0x%x\n", pw[i] );
  259. */
  260.  
  261.     for ( i = 0; i < pPix->drawable.height; ++i ) {
  262.     pdst = line;
  263.     for(j = 0; j < pPix->drawable.width; j++) {
  264.         *pdst++ = *psrc++ ? 'X' : ' ' ;
  265.     }
  266.     *pdst++ = '\n';
  267.     *pdst++ = '\0';
  268.     ErrorF( "%s", line);
  269.     }
  270. }
  271. #endif /* notdef */
  272.  
  273. /* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that
  274.  * words are 32 bits wide, and that the least significant bit appears on the
  275.  * left.
  276.  */
  277. void
  278. cfbXRotatePixmap(pPix, rw)
  279.     PixmapPtr    pPix;
  280.     register int rw;
  281. {
  282.     register unsigned int    *pw, *pwFinal;
  283.     register unsigned int    t;
  284.  
  285.     if (pPix == NullPixmap)
  286.         return;
  287.  
  288.     switch (((DrawablePtr) pPix)->depth) {
  289.     case PSZ:
  290.         break;
  291.     case 1:
  292.         mfbXRotatePixmap(pPix, rw);
  293.         return;
  294.     default:
  295.         ErrorF("cfbXRotatePixmap: unsupported depth %d\n", ((DrawablePtr) pPix)->depth);
  296.         return;
  297.     }
  298.     pw = (unsigned int *)pPix->devPrivate.ptr;
  299.     rw %= pPix->drawable.width;
  300.     if (rw < 0)
  301.     rw += pPix->drawable.width;
  302.     if(pPix->drawable.width == PPW)
  303.     {
  304.         pwFinal = pw + pPix->drawable.height;
  305.     while(pw < pwFinal)
  306.     {
  307.         t = *pw;
  308.         *pw++ = SCRRIGHT(t, rw) |
  309.             (SCRLEFT(t, (PPW-rw)) & cfbendtab[rw]);
  310.     }
  311.     }
  312.     else
  313.     {
  314.         ErrorF("cfb internal error: trying to rotate odd-sized pixmap.\n");
  315. #ifdef notdef
  316.     register unsigned int *pwTmp;
  317.     int size, tsize;
  318.  
  319.     tsize = PixmapBytePad(pPix->drawable.width - rw, PSZ);
  320.     pwTmp = (unsigned int *) ALLOCATE_LOCAL(pPix->drawable.height * tsize);
  321.     if (!pwTmp)
  322.         return;
  323.     /* divide pw (the pixmap) in two vertically at (w - rw) and swap */
  324.     tsize >>= 2;
  325.     size = pPix->devKind >> 2;
  326.     cfbQuickBlt((int *)pw, (int *)pwTmp,
  327.             0, 0, 0, 0,
  328.             (int)pPix->drawable.width - rw, (int)pPix->drawable.height,
  329.             size, tsize);
  330.     cfbQuickBlt((int *)pw, (int *)pw,
  331.             (int)pPix->drawable.width - rw, 0, 0, 0,
  332.             rw, (int)pPix->drawable.height,
  333.             size, size);
  334.     cfbQuickBlt((int *)pwTmp, (int *)pw,
  335.             0, 0, rw, 0,
  336.             (int)pPix->drawable.width - rw, (int)pPix->drawable.height,
  337.             tsize, size);
  338.     DEALLOCATE_LOCAL(pwTmp);
  339. #endif
  340.     }
  341. }
  342.  
  343. /* Rotates pixmap pPix by h lines.  Assumes that h is always less than
  344.    pPix->drawable.height
  345.    works on any width.
  346.  */
  347. void
  348. cfbYRotatePixmap(pPix, rh)
  349.     register PixmapPtr    pPix;
  350.     int    rh;
  351. {
  352.     int nbyDown;    /* bytes to move down to row 0; also offset of
  353.                row rh */
  354.     int nbyUp;        /* bytes to move up to line rh; also
  355.                offset of first line moved down to 0 */
  356.     char *pbase;
  357.     char *ptmp;
  358.  
  359.     if (pPix == NullPixmap)
  360.     return;
  361.     switch (((DrawablePtr) pPix)->depth) {
  362.     case PSZ:
  363.         break;
  364.     case 1:
  365.         mfbYRotatePixmap(pPix, rh);
  366.         return;
  367.     default:
  368.         ErrorF("cfbYRotatePixmap: unsupported depth %d\n", ((DrawablePtr) pPix)->depth);
  369.         return;
  370.     }
  371.  
  372.     rh %= pPix->drawable.height;
  373.     if (rh < 0)
  374.     rh += pPix->drawable.height;
  375.  
  376.     pbase = (char *)pPix->devPrivate.ptr;
  377.  
  378.     nbyDown = rh * pPix->devKind;
  379.     nbyUp = (pPix->devKind * pPix->drawable.height) - nbyDown;
  380.     if(!(ptmp = (char *)ALLOCATE_LOCAL(nbyUp)))
  381.     return;
  382.  
  383.     bcopy(pbase, ptmp, nbyUp);        /* save the low rows */
  384.     bcopy(pbase+nbyUp, pbase, nbyDown);    /* slide the top rows down */
  385.     bcopy(ptmp, pbase+nbyDown, nbyUp);    /* move lower rows up to row rh */
  386.     DEALLOCATE_LOCAL(ptmp);
  387. }
  388.  
  389. void
  390. cfbCopyRotatePixmap(psrcPix, ppdstPix, xrot, yrot)
  391.     register PixmapPtr psrcPix, *ppdstPix;
  392.     int    xrot, yrot;
  393. {
  394.     register PixmapPtr pdstPix;
  395.  
  396.     if ((pdstPix = *ppdstPix) &&
  397.     (pdstPix->devKind == psrcPix->devKind) &&
  398.     (pdstPix->drawable.height == psrcPix->drawable.height))
  399.     {
  400.     bcopy((char *)psrcPix->devPrivate.ptr,
  401.           (char *)pdstPix->devPrivate.ptr,
  402.           psrcPix->drawable.height * psrcPix->devKind);
  403.     pdstPix->drawable.width = psrcPix->drawable.width;
  404.     pdstPix->drawable.depth = psrcPix->drawable.depth;
  405.     pdstPix->drawable.bitsPerPixel = psrcPix->drawable.bitsPerPixel;
  406.     pdstPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  407.     }
  408.     else
  409.     {
  410.     if (pdstPix)
  411.         cfbDestroyPixmap(pdstPix);
  412.     *ppdstPix = pdstPix = cfbCopyPixmap(psrcPix);
  413.     if (!pdstPix)
  414.         return;
  415.     }
  416.     cfbPadPixmap(pdstPix);
  417.     if (xrot)
  418.     cfbXRotatePixmap(pdstPix, xrot);
  419.     if (yrot)
  420.     cfbYRotatePixmap(pdstPix, yrot);
  421. }
  422.